package com.iwhalecloud.citybrain.flow.platform.manager.application.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.iwhalecloud.citybrain.flow.platform.manager.application.event.EventCallURL;
import com.iwhalecloud.citybrain.flow.platform.manager.application.event.EventResponse;
import com.iwhalecloud.citybrain.flow.platform.manager.application.event.NodeEventExecuter;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.SpringUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.exception.EventCallException;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.exception.EventCallSuspendException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.common.api.variable.VariableContainer;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.flowable.engine.impl.el.*;

import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class ExternalApiDelegate implements JavaDelegate {
    private FixedValue requestUrl;
    private FixedValue requestBody;
    private FixedValue resultVariable;

    @Override
    public void execute(DelegateExecution execution) {
        log.info("===========ExternalApiDelegate==========================");
        // 解析url
        if (null == requestUrl) {
            log.info("ExternalApiDelegate未配置事件URL");
            return;
        }
        String externalURL = (String) requestUrl.getValue(execution);
        log.info("ExternalApiDelegate 解析前的请求地址:{}", externalURL);

        String executionId = execution.getId();
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
        ExecutionEntity executionEntity = executionEntityManager.findById(executionId);
        Map<String, Object> variables = executionEntity.getVariables();

        log.info(JSON.toJSONString(variables, SerializerFeature.PrettyFormat));

        EventCallURL eventCallURL = new EventCallURL(execution);
        String parsedUrl = eventCallURL.parseStr(externalURL);
        if (parsedUrl == null) {
            log.error("流程变量解析失败: {}", externalURL);
        }
        log.info("ExternalApiDelegate解析后的请求地址：{}", parsedUrl);
        String externalRequestBody = "";
        if (null != requestBody) {
            externalRequestBody = (String) requestBody.getValue(execution);
            log.info("ExternalApiDelegate解析前的请求体：{}", externalRequestBody);
        }
        externalRequestBody = eventCallURL.parseStr(externalRequestBody);
        log.info("ExternalApiDelegate解析后的请求体：{}", externalRequestBody);

        NodeEventExecuter nodeEventExecuter = SpringUtils.getBean(NodeEventExecuter.class);
        try {
            EventResponse eventResponse = nodeEventExecuter.syncCall(parsedUrl, externalRequestBody);
            if (Objects.isNull(eventResponse)) {
                log.error("事件接口返回结果为空，无法判断接口调用是否成功，url:{}", parsedUrl);
            }
            if (!eventResponse.isSuccess()) {
                StringBuilder msg = new StringBuilder("事件接口调用异常，异常信息为：");
                if (StringUtils.isNotBlank(eventResponse.getMsg())) {
                    msg.append(eventResponse.getMsg());
                }
                msg.append(",url=").append(parsedUrl);
                log.error(msg.toString());
            }
            log.info("ExternalApiDelegate Sync EventCall response：{}", eventResponse);
            // TODO:
            execution.setVariable(resultVariable.getValue(execution).toString(), true);
//            execution.setVariable(resultVariable.getValue(execution).toString(), eventResponse.getData());
        } catch (EventCallException e) {
            log.error("ExternalApiDelegate Sync EventCall Error:", e);
        }
    }

    public Boolean getPost() {
        log.info("============post===================");
        return true;
    }
}
